package com.rookie.data.generate.component.generate;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.rookie.data.generate.constant.annotation.StringTemplate;
import com.rookie.data.generate.constant.enums.ColumnRangeEnum;
import com.rookie.data.generate.constant.HighRateWord;
import com.rookie.data.generate.model.project.FieldProperties;
import com.rookie.data.generate.model.project.TableColumnEntity;
import com.rookie.data.generate.util.GenerateUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.Arrays;
import java.util.List;

/**
 * 字符串生成工具
 *
 * @author rookie
 */
public class StringGenerate {

    private static final List<String> FIX_WIDTH_TYPE = Arrays.asList("VARCHAR", "CHAR");

    public static Object generate(TableColumnEntity table, FieldProperties properties, ColumnRangeEnum columnRangeEnum) {
        String str = "(";
        if (properties == null) {
            properties = new FieldProperties();
        }
//        处理字符常量
        if (properties.getStringTemplate() != null) {
            return processStringTemplate(properties.getStringTemplate());
        }
        String columnType = table.getDataType().toUpperCase();
        if (StringUtils.isNotBlank(table.getColumnType()) && table.getColumnType().contains(str) && FIX_WIDTH_TYPE.contains(columnType)) {
//          处理固定大小的字符类型
            processStringRange(table, properties);
        }
        int[] range = GenerateUtils.getRange(properties, columnRangeEnum);
        if (StringUtils.isNotBlank(table.getColumnKey())) {
            String s = processPrimary(table, range);
            if (s != null) {
                return s;
            }
        }
        return generateString(range);
    }

    private static String generateString(int[] range) {
        int charNum = range[0] + GenerateUtils.RANDOM.nextInt(range[1] - range[0]);
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < charNum; i++) {
            builder.append(getHighRateChar(1));
        }
        return builder.toString();
    }

    private static String generateUnique(int[] range) {
        if (range[0] < 36 && range[1] > 36) {
            return IdWorker.getTimeId();
        } else if (range[0] < 32 && range[1] > 32) {
            return IdWorker.get32UUID();
        } else if (range[0] < 19 && range[1] > 19) {
            return IdWorker.getIdStr();
        } else if (range[0] < 17 && range[1] > 17) {
            return IdWorker.getMillisecond();
        }
        return null;
    }

    public static char getHighRateChar(int type) {
        int num = 0;
        switch (type) {
            case 1:
                num = GenerateUtils.RANDOM.nextInt(HighRateWord.HIGH_RATE_WORDS.size() - 1);
                return HighRateWord.HIGH_RATE_WORDS.get(num);
            case 2:
                num = GenerateUtils.RANDOM.nextInt(HighRateWord.LINES_WORDS.size() - 1);
                return HighRateWord.LINES_WORDS.get(num);
            case 3:
                num = GenerateUtils.RANDOM.nextInt(HighRateWord.NET_WORDS.size() - 1);
                return HighRateWord.NET_WORDS.get(num);
            default:
                return '嘿';
        }
    }

    /**
     * 生成汉字，繁体居多
     *
     * @return 汉字
     */
    private static char getRandomChar() {
        return (char) (0x4e00 + (int) (Math.random() * (0x5208 - 0x4e00 + 1)));
    }

    private static void processStringRange(TableColumnEntity table, FieldProperties properties) {
        String str = "(";
        Integer maxSize = Integer.parseInt(table.getColumnType().substring(table.getColumnType().indexOf(str))
                .replace("(", "")
                .replace(")", "")
                .trim());

        if (properties.getMaxValue() == null || properties.getMaxValue() >= maxSize) {
            properties.setMaxValue(maxSize);
        }
    }

    /**
     * 处理主键数据
     */
    private static String processPrimary(TableColumnEntity table, int[] range) {
        //            主键
        if ("PRI".equalsIgnoreCase(table.getColumnKey())) {
            if (range[0] > 19 || range[1] < 19) {
                throw new RuntimeException(table.getColumnName() + "字段长度不在规则范围内，生成失败");
            }
        } else if ("UNI".equalsIgnoreCase(table.getColumnKey())) {
//                唯一索引
            return generateUnique(range);
        }
        return null;
    }

    private static String processStringTemplate(StringTemplate stringTemplate) {
        return String.format(stringTemplate.value(), switchType(stringTemplate.type()));
    }

    private static Object[] switchType(StringTemplate.StringTemplateTypeEnum[] arr) {
        Object[] result = new Object[arr.length];
        for (int i = 0; i < arr.length; i++) {
            switch (arr[i]) {
                case INT:
                    result[i] = NumberGenerate.generateInt(new FieldProperties(), ColumnRangeEnum.INT);
                    break;
                case STRING:
                    result[i] = getHighRateChar(2);
                    break;
                default:
                    result[i] = "";
                    break;
            }
        }
        return result;
    }
}
